home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Free Software Collection: Marty 1
/
FM Towns Marty 1 Free Software Collection.iso
/
tool
/
book
/
src
/
keyio.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-11-11
|
9KB
|
328 lines
/*
* keyboard low I/O
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string.h>
#include <ctype.h>
#include <egb.h>
#include <mos.h>
#include <fmc.h>
#include "book.h"
#include "oaklib.h"
#include "keyio.h"
#include "lib.h"
#include "menu_evt.h"
#include "init.h"
/*
* エンコード・モードのキー入力
*/
static int kb_char = 0xFFFF;
static u_int kb_encode = 0;
#if 0 /* Break/COPY の検出をするときは、"1" にする */
static u_char matrix[16];
static u_int now_break = OFF, now_copy = OFF;
static u_int last_break = OFF, last_copy = OFF;
int kbhit(void)
{
last_break = now_break, last_copy = now_copy;
KYB_matrix((char *)matrix);
now_break = ((matrix[15]) & 0x10) != 0 ? ON:OFF;
now_copy = ((matrix[15]) & 0x20) != 0 ? ON:OFF;
if (last_break == ON && now_break == OFF)
{
kb_char = 0x8000, kb_encode = 0x7C00;
return 1;
}
if (last_copy == ON && now_copy == OFF)
{
kb_char = 0x8000, kb_encode = 0x7D00;
return 1;
}
if (kb_char != 0xFFFF || (kb_char = KAN_read(1, &kb_encode)) != 0xFFFF)
return 1;
else
return 0;
}
#else
int kbhit(void)
{
if (kb_char != 0xFFFF || (kb_char = KAN_read(1, &kb_encode)) != 0xFFFF)
return 1;
else
return 0;
}
#endif
static u_char _cnvtbl[] =
{ /* このキーアドレスだったら、「0x8000 + キーアドレス」に変換する */
0x4D, /* ↑ */ 0x4F, /* ← */
0x50, /* ↓ */ 0x51, /* → */
0x01, /* ESC */ 0x10, /* TAB */
0x57, /* 無変換 */ 0x58, /* 変換 */
0x59, /* かな漢字 */ 0x5A, /* カナ */
0x56, /* ひらがな */
0x1D, /* 改行 */ 0x45, /* 改行(テンキー) */
0x73, /* 実行 */ 0x72, /* 取消 */
0x0F, /* BS */ 0x48, /* 挿入 */
0x6B, /* 漢字辞書 */ 0x6C, /* 単語抹消 */
0x6D, /* 単語登録 */ 0x4E, /* HOME */
0x6E, /* 前行 */ 0x70, /* 次行 */
0x71, /* 半角/全角 */ 0x4B, /* 削除 */
0x7C, /* BREAK */ 0x7D, /* COPY */
0x5D, /* PF1 */ 0x5E, /* PF2 */
0x5F, /* PF3 */ 0x60, /* PF4 */
0x61, /* PF5 */ 0x62, /* PF6 */
0x63, /* PF7 */ 0x64, /* PF8 */
0x65, /* PF9 */ 0x66, /* PF10 */
0x69, /* PF11 */ 0x5B, /* PF12 */
0x74, /* PF13 */ 0x75, /* PF14 */
0x76, /* PF15 */ 0x77, /* PF16 */
0x78, /* PF17 */ 0x79, /* PF18 */
0x7A, /* PF19 */ 0x7B, /* PF20 */
};
static char cnvtbl[256]; /* こっちが本当のテーブル */
void kb_setup_cnvtbl(void)
{
int i;
memset(cnvtbl, '\0', 256);
for (i = 0; i < sizeof(_cnvtbl)/sizeof(u_char); i++)
cnvtbl[_cnvtbl[i]] = '\1';
}
/*
* キーボードからの一文字入力 (入力待ちをおこなう)
*
* 入力
* なし
* 出力
* int ch - 入力されたキー情報がパックされて返される
* PF, 機能キー → bit 8 セット
* bit 0-7 キーアドレス
* bit12-15 シフト状態
* 通常キー → bit 8 リセット
* bit 0-7 キャラクタコード
* ただし、シフト状態として返されるのは、bit12,13,14,15
* (シフト、コントロール、左右親指シフト)のみ
*/
int getch(void)
{
int ch;
do {
while (kbhit() == 0) /* 入力待ち */
;
ch = kb_char; kb_char = 0xFFFF;
} while (ch == 0);
if (cnvtbl[kb_encode >> 8]) {
ch = (kb_encode >> 8) | /* bit 0~7 はキーアドレス */
(1 << 8) | /* bit 8 をセット */
((kb_encode & 0x04) << 10) | /* bit12 はシフトキー */
((kb_encode & 0x70) << 9); /* bit13~15 はのこり */
}
return ch;
}
void keyflush(void)
{
KYB_clrbuf();
while (kbhit())
getch();
}
/*
* キーアサインの保存と復元
*/
typedef struct {
short sw, code, chrcnt;
char buf[16];
} kb_tbl_t;
typedef struct {
kb_tbl_t tbl[48];
int num; /* いくつのキーアサインを保存したか */
} asign_t;
static asign_t asign[ASIGN_PUSH_MAX];
static int asign_num = 0;
void kb_asign_push( void )
{
asign_t *ap ;
int i ;
if( asign_num >= ASIGN_PUSH_MAX ) /* これ以上保存できない */
return ;
ap = &asign[asign_num++] ;
void rdassign( asign_t *ap, int code, int num )
{
int sw, chrcnt ;
char buf[32] = "\x0F" ;
KYB_rdasign( &sw, code, &chrcnt, buf ) ;
ap->tbl[num].sw = sw ;
ap->tbl[num].code = code ;
ap->tbl[num].chrcnt = chrcnt ;
memcpy( ap->tbl[num].buf, buf+1, chrcnt ) ;
ap->tbl[num].buf[chrcnt] = '\0' ;
}
ap->num = 0 ;
#if 0
for( i = 0x8001 ; i <= 0x800B ; i++, ap->num++ )
rdassign( ap, i, ap->num ) ;
for( i = 0x8011 ; i <= 0x8018 ; i++, ap->num++ )
rdassign( ap, i, ap->num ) ;
for( i = 0x801c ; i <= 0x801f ; i++, ap->num++ )
rdassign( ap, i, ap->num ) ;
for( i = 0x8021 ; i <= 0x8028 ; i++, ap->num++ )
rdassign( ap, i, ap->num ) ;
#endif
for( i = 0x8001 ; i <= 0x8028 ; i++, ap->num++ )
rdassign( ap, i, ap->num ) ;
rdassign( ap, 0x7F, ap->num++ ) ;
}
void kb_asign_pop( void )
{
asign_t *ap ;
int i ;
if( asign_num < 1 ) /* 保存されていない */
return ;
ap = &asign[--asign_num] ;
for( i = 0 ; i < ap->num ; i++ )
KYB_asign( ap->tbl[i].sw,
ap->tbl[i].code, ap->tbl[i].chrcnt, ap->tbl[i].buf ) ;
}
/*
* マトリクスによるキー入力
*/
static int active_char = 0; /* 現在押されているキーアドレス */
static u_int start_time = 0; /* ↑が押し始められた時間 */
static int repeat_start = FALSE; /* リピート開始フラグ */
/* キーボード入力チェック */
static int _kb_check(void)
{
#define BITS (8) /* バイト型のビット数 */
#define pSHIFT (0x53 / BITS) /* シフトキーのバイト位置 */
#define mSHIFT (1<<(0x53 % BITS)) /* シフトキーのビット位置 */
#define pCTRL (0x52 / BITS) /* コントロールキーのバイト位置 */
#define mCTRL (1<<(0x52 % BITS)) /* コントロールキーのビット位置 */
#ifdef USE_OYAYUBI
# define pLSHIFT (0x67 / BITS) /* 左親指シフトキーのバイト位置 */
# define mLSHIFT (1<<(0x67 % BITS)) /* 左親指シフトキーのビット位置 */
# define pRSHIFT (0x68 / BITS) /* 右親指シフトキーのバイト位置 */
# define mRSHIFT (1<<(0x68 % BITS)) /* 右親指シフトキーのビット位置 */
#endif
static u_long matrix[4];
u_char *p = (u_char *)matrix;
u_long i, val;
u_long shift = 0;
KYB_matrix((char *)matrix);
shift |= (p[pSHIFT ] & mSHIFT ) ? 0x100 : 0; /* シフトキー */
p[pSHIFT] &= (0xFF ^ mSHIFT);
shift |= (p[pCTRL ] & mCTRL ) ? 0x200 : 0; /* コントロールキー */
p[pCTRL] &= (0xFF ^ mCTRL);
#ifdef USE_OYAYUBI
shift |= (p[pLSHIFT] & mLSHIFT) ? 0x400 : 0; /* 左親指シフト */
p[pLSHIFT] &= (0xFF ^ mLSHIFT);
shift |= (p[pRSHIFT] & mRSHIFT) ? 0x800 : 0; /* 左親指シフト */
p[pRSHIFT] &= (0xFF ^ mRSHIFT);
#endif
if (matrix[0] || matrix[1] || matrix[2] || matrix[3])
{
KYB_clrbuf();
for (i = 0; i < 16; i++)
{
if ((val = p[i]) != 0)
{
for (i *= 8; (val & 1) == 0; i++)
val >>= 1;
return shift | i;
}
}
}
return shift;
}
int kb_check(void)
{
int code;
code = _kb_check();
if (active_char != code)
{
active_char = code; /* 現在押されているキーアドレス */
start_time = MOS_getTime(); /* ↑が押し始められた時間 */
repeat_start = FALSE; /* リピート開始フラグ */
}
return code;
}
/* キーから手を離すか、リピート時間が経過すると復帰する */
void wait_repeat(void)
{
int code = active_char;
int start = start_time;
int last = MOS_getTime();
while (code == _kb_check()) /* キーが押されていたら */
{
if (repeat_start) /* リピート中 */
{
if (MOS_getTime() - last > setup.repeat)
break;
}
else /* リピート開始待ち */
{
if (MOS_getTime() - start > setup.repstart) {
repeat_start = TRUE;
break;
}
}
}
}